如何使用LibreOffice API + Python通过暴力破解的方式找到忘记的Office文件密码

发表于

分类:

今天群里有人问了一个问题:忘记了ods电子表格文档的密码,怎么办?

我简单想了想,得出简单结论:如果你大概知道自己当时设置的密码的规律(比如,密码的长度,密码中包含哪些字符,是纯数字还是数字字母组合),那么可以通过编程的方式通过依次尝试的暴力破解方式找到密码。

以下是初步的代码。例子中使用的虽然是一个ods文档,但理论上任何能通过LibreOffice打开的文件都适用。

# -*- coding: utf-8 -*-
''' Simple python script to hack an office document password.
Usage:
1. Start a LibreOffice process (headless mode):
/opt/libreoffice/program/soffice.bin --accept=socket,host="localhost,port=2002;urp;" --headless
2. Run the script using the python binary bundled with LibreOffice:
/opt/libreoffice/program/python /home/suokunlong/Documents/hack.py
'''

import random

import uno
from com.sun.star.beans import PropertyValue

ods = "file:////home/suokunlong/Documents/test.ods"

localContext = uno.getComponentContext()
resolver = localContext.ServiceManager.createInstanceWithContext(
    "com.sun.star.bridge.UnoUrlResolver", localContext)
ctx = resolver.resolve( "uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext")
smgr = ctx.ServiceManager
desktop = smgr.createInstanceWithContext( "com.sun.star.frame.Desktop", ctx)

arg_pw = PropertyValue()
arg_pw.Name = "Password"

model = None
possibleDigits = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]
passwordLength = 6

# When fileopen is successful, loadComponentFromURL returns a com::sun::star::lang::XComponent instance.
# Otherwise, it returns NULL.
# Try each password to see wether the returned value is true.
while not model:
	possiblePassword = ""
	for i in range(0, passwordLength):
		rd = random.randint(0, len(possibleDigits)-1)
		possiblePassword += possibleDigits[rd]
	arg_pw.Value = possiblePassword
	print(possiblePassword)
	model = desktop.loadComponentFromURL(ods, "_blank", 0, (arg_pw,))

print("The password of the document is: ", password)

当然,这种方法效率会比较低,通过从可能的密码字符中随机组合的方式猜测、并且是单线程处理的情况下,可能需要跑很长时间才能中招。可以通过多线程、常用密码字典等、甚至是GPU计算等方式进行优化。


评论:

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注